package org.etom.impl.ui.common;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.WorkbenchException;
import org.etom.connector.datatypes.IMoodleConnection;
import org.etom.impl.ui.util.CommonMessages;

/**
 * Wrapper over tree viewer which updates the view and data model. 
 */
public final class ResourcesTreeViewer {

  private TreeViewer treeViewer;
  private ResourcesDataProvider resourcesDataProvider;
  private Object rootElement;
  
  public ResourcesTreeViewer(TreeViewer treeViewer, int type) {
    if (null == treeViewer) throw new NullPointerException(
        CommonMessages.Tree_Viewer_Null);
    this.treeViewer = treeViewer;
    init(type);
  }

  
  /**
   * The method returns the selected connections.
   * 
   * @return - the selected connections,
   *  the result can not be <code>null</code>, but can be empty
   */
  public IMoodleConnection[] getSelectedConnections() {
    IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
    Object currentElem;
    List<IMoodleConnection> result = new ArrayList<IMoodleConnection>();
    for (Iterator<?> iterator = selection.iterator(); iterator.hasNext(); /*empty*/) {
      currentElem = iterator.next();
      if (currentElem instanceof IMoodleConnection) {
        result.add((IMoodleConnection) currentElem);
      }
    }
    return result.toArray(new IMoodleConnection[result.size()]);
  }
  
  /**
   * The method returns all selected elements.
   * @return
   */
  public Object getSelection() {
    IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
    return selection.getFirstElement();
  }
  
  /**
   * The method stores the connections form the buffer.
   * 
   * @throws IOException if an error is occurred in the save operation
   */
  public void save() throws IOException {
    resourcesDataProvider.save();
  }
  
  /**
   * Loads the stored connection in the buffer.
   * 
   * @throws WorkbenchException if an error is occurred in the load operation
   */
  public void load() throws WorkbenchException {
    IMoodleConnection[] loadedConnections = resourcesDataProvider.load();
    if (loadedConnections == null) return;
    treeViewer.add(rootElement, loadedConnections);
  }
  
  /**
   * Refreshes the resources viewer with the data obtained
   * from the model.
   */
  public void refresh() {
    treeViewer.refresh();
  }
  
  /**
   * The method removes the moodle connections from data model and
   * refreshes the view.
   * 
   * @param moodleConnections - the connections which will be removed
   * 
   * @return return <code>true</code> if some of the connections are removed
   */
  public boolean removeMoodleConnections(IMoodleConnection[] moodleConnections) {
    if (resourcesDataProvider.removeMoodleConnections(moodleConnections)) {
      treeViewer.remove(moodleConnections);
      return true;
    }
    return false;
  }
  
  /**
   * The method adds the connectin to the model and refreshes the view.
   * 
   * @param moodleConnection - a new connection
   */
  public void addMoodleConnection(IMoodleConnection moodleConnection) {
    if (moodleConnection == null) return;
    resourcesDataProvider.addMoodleConnection(moodleConnection);
    treeViewer.add(rootElement, moodleConnection);
  }
  
  /*
   * An utility method which initializes the viewer. 
   */
  private void init(int type) {
    resourcesDataProvider = new ResourcesDataProvider();
    rootElement = new Object();
    ResourcesTreeProvider resourcesTreeProvider =
      new ResourcesTreeProvider(rootElement, resourcesDataProvider, type);
    treeViewer.setContentProvider(resourcesTreeProvider);
    treeViewer.setLabelProvider(resourcesTreeProvider);
    treeViewer.setInput(rootElement);
    
    //add tool tip manager
    Tree tree = treeViewer.getTree();
    TreeViewerToolTipManager toolTipManager =
      new TreeViewerToolTipManager(tree, tree.getShell(), tree.getShell().getDisplay());
    tree.addListener (SWT.Dispose, toolTipManager);
    tree.addListener (SWT.KeyDown, toolTipManager);
    tree.addListener (SWT.MouseMove, toolTipManager);
    tree.addListener (SWT.MouseHover, toolTipManager);
  }
  
}
